package com.example.netty.netty.groupChat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.concurrent.GlobalEventExecutor;

import javax.lang.model.element.VariableElement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

public class ServerHandler extends SimpleChannelInboundHandler<String> {
    //相当于channel列表，来用管理所有的channel
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    //与handler建立连接时触发
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        //将该通道加入管理列表
        channelGroup.add(ctx.channel());
        //通知信息,发送给所有人
        channelGroup.writeAndFlush(dateFormat.format(new Date())+"-客户端："
                +ctx.channel().remoteAddress()+" 加入聊天\n");
    }

    //断开连接时触发
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        channelGroup.writeAndFlush(dateFormat.format(new Date())+"-客户端："
                +ctx.channel().remoteAddress()+" 离开了\n");
    }

    // TODO: 2022/9/12 与上面两个方法的区别？
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(dateFormat.format(new Date())+ctx.channel().remoteAddress()+" 上线了");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(dateFormat.format(new Date())+ctx.channel().remoteAddress()+" 下线了");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        Channel channel = channelHandlerContext.channel();
        channelGroup.forEach(ch->{
            if (ch != channel) {
                ch.writeAndFlush(dateFormat.format(new Date())+"-客户端：" + channel.remoteAddress() + " 说：" + s + "\n");
            } else {
                //回显
                ch.writeAndFlush(dateFormat.format(new Date())+"-自己说："+s+"\n");
            }
        });
    }

    //空闲时触发
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            String eventType = null;
            switch (event.state()) {
                case READER_IDLE:eventType = "读空闲";break;
                case WRITER_IDLE:eventType = "写空闲";break;
                case ALL_IDLE:eventType = "读写空闲";break;
            }
            System.out.println(ctx.channel().remoteAddress()+" "+eventType+" 正在执行空闲逻辑。。。");
            ctx.channel().close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        cause.printStackTrace();
        ctx.close();
    }
}











